/*
 * DEMElementTest.cpp
 *
 *  Created on: 03/may/2013
 *      Author: lordmzn
 */
#include <gtest/gtest.h>
#include "MOLEM/DEMElement.h"

namespace MOLEMTests {

class DEMElementTest : public ::testing::Test {

public:
	DEMElementTest() : val(13.0) {
	}
	double val;
};

TEST_F(DEMElementTest, ConstructorsTest) {
	// construct element
	MOLEM::DEMElement a(1,1);
	ASSERT_EQ(MOLEM::ELEMENT_Z_DEFAULT_VALUE, a.getZvalue()) << "init of z value failed";
	a.setZvalue(val);
	ASSERT_EQ(val, a.getZvalue()) << "set/get of z value failed";
	// isFunctions() test
	ASSERT_FALSE(a.isASink());
	ASSERT_FALSE(a.isASpring());
	ASSERT_FALSE(a.isConnected());
	ASSERT_FALSE(a.isDirectionEvaluated());
	ASSERT_FALSE(a.isElementsAccumulationEvaluated());
	ASSERT_FALSE(a.isGradientEvaluated());
	MOLEM::DEMElement b(a);
	ASSERT_EQ(a, b) << "copy constructor doesn't work";
	a.setZvalue(val*val);
	ASSERT_EQ(val*val, a.getZvalue()) << "reset doesn't work";
	ASSERT_NE(b.getZvalue(), a.getZvalue()) << "reset doesn't work";
	ASSERT_FALSE(a.isASink());
	ASSERT_FALSE(a.isASpring());
	ASSERT_FALSE(a.isDirectionEvaluated());
	ASSERT_FALSE(a.isElementsAccumulationEvaluated());
	ASSERT_FALSE(a.isGradientEvaluated());
}

TEST_F(DEMElementTest, DirectionTest) {
	// construct elements and connect
	MOLEM::DEMElement e00(0,0);
	MOLEM::DEMElement e10(1,0);
	MOLEM::DEMElement e20(2,0);
	MOLEM::DEMElement e01(0,1);
	MOLEM::DEMElement e11(1,1);
	MOLEM::DEMElement e21(2,1);
	MOLEM::DEMElement e02(0,2);
	MOLEM::DEMElement e12(1,2);
	MOLEM::DEMElement e22(2,2);
	e00.connect(e00, e00, e01, e10);
	e10.connect(e10, e00, e11, e20);
	e20.connect(e20, e10, e02, e20);
	e01.connect(e00, e01, e02, e11);
	e11.connect(e10, e01, e12, e21);
	e21.connect(e20, e11, e22, e21);
	e02.connect(e01, e02, e02, e12);
	e12.connect(e11, e02, e12, e22);
	e22.connect(e21, e12, e22, e22);
	ASSERT_TRUE(e11.isConnected()) << "fails to connect the central element!";

	// set Z value
	e00.setZvalue(val+4);
	e10.setZvalue(val+3);
	e20.setZvalue(val+2);
	e01.setZvalue(val+4);
	e11.setZvalue(val+1);
	e21.setZvalue(val+1);
	e02.setZvalue(val+3);
	e12.setZvalue(val+2);
	e22.setZvalue(val);

	// evaluate directions
	e00.markAsSpring();
	e01.markAsSpring();
	e00.findDirection();
	ASSERT_TRUE(e00.isDirectionEvaluated()) << "fails to find dir for e00";
	ASSERT_TRUE(e11.isDirectionEvaluated()) << "fails to find dir for e11";
	ASSERT_TRUE(e22.isElementsAccumulationEvaluated()) << "fails to add accumulation on e22";
	ASSERT_TRUE(e22.isASink()) << "fails to mark e22 as a sink";
}

} /* namespace MOLEMTests */
